#include <Camera.hpp>
#include <Matrix4.hpp>

using namespace Olorin::Framework;

namespace Olorin
{
	Camera::Camera() : Object()
	{
		this->up = Vector3(0,1,0); //Vector3::UnitY;
		this->lookAt = Vector3(0,0,1);//Vector3::UnitZ;
		this->fieldOfView = 3.14159f / 2;
		this->aspectRatio = 1;
		this->nearPlane = 1;
		this->farPlane = 1000;
	}

	// Mutators
	void Camera::setUp(const Vector3& up)
	{
		this->up - up;
	}

	void Camera::setLookAt(const Vector3& lookAt)
	{
		this->lookAt - lookAt;
	}

	void Camera::setFieldOfView(const float& fieldOfView)
	{
		this->fieldOfView = fieldOfView;
	}

	void Camera::setAspectRatio(const float& aspectRatio)
	{
		this->aspectRatio = aspectRatio;
	}

	void Camera::setNearPlane(const float& nearPlane)
	{
		this->nearPlane = nearPlane;
	}

	void Camera::setFarPlane(const float& farPlane)
	{
		this->farPlane = farPlane;
	}

	// Accessors
	const Vector3& Camera::getUp() const
	{
		return up;
	}

	const Vector3& Camera::getLookAt() const
	{
		return lookAt;
	}

	const float& Camera::getFieldOfView() const
	{
		return fieldOfView;
	}

	const float& Camera::getAspectRatio() const
	{
		return aspectRatio;
	}

	const float& Camera::getNearPlane() const
	{
		return nearPlane;
	}

	const float& Camera::getFarPlane() const
	{
		return farPlane;
	}

	// Camera functions
	const Vector3 Camera::getForward() const
	{
		return Vector3::transformNormal(lookAt, Matrix4::createRotationQuaternion(getRotation()));
	}

	const Matrix4 Camera::getView() const
	{
		return Matrix4::createLookAt(getPosition(),getForward(),Vector3::transformNormal(up, Matrix4::createRotationQuaternion(getRotation())));
	}

	const Matrix4 Camera::getProjection() const
	{
		return Matrix4::createPerspective(fieldOfView, aspectRatio, nearPlane, farPlane);
	}
}